/**
 * by leili
 * constructor parent是UI.Selector实例的容器
 * class selector_veil 为半透明的选择拉膜的样式，selector_cancel，selector_select
 */
UI.Selector = Class.create({
	initialize : function(parent) {
		this.parent = $(parent);
		this.parent.setStyle({position:"relative",cursor:"crosshair"});
		this.parent.oncontextmenu = function(){return false};
		this.parent.onselectstart = function(){return false};
		this.mouseMove = this.mouseMove.bindAsEventListener(this);
		this.mouseUp  = this.mouseUp.bindAsEventListener(this);
		var me = this;
		this.childs = $A(this.parent.getElementsByTagName("div"));
		this.childs.without(this.veil).each((function(div){
			$(div).setStyle({cursor:"pointer"});
			
			$(div)._clickListener = (function(event){
				var data = $A(arguments);
				if(!event.ctrlKey){
					//no press ctrl
					this.childs.without(this.veil).each((function(value){
						this.cancel(value);
					}).bind(this));
				}
				if(data[1].selected)
					this.cancel(data[1]);
				else
					this.select(data[1]);
			}).bindAsEventListener(this,$(div));
			
			$(div).observe("click",$(div)._clickListener);
		}).bind(this));
		
		this.veil = new Element("div");
		this.veil.addClassName("selector_veil");
		this.veil.setStyle({zIndex:98,position:"absolute"});
		this.veil.setStyle({left:"0px",top:"0px",width:"0px",height:"0px"});
		this.veil.setOpacity(0.5);
		this.veil.hide();
		this.parent.insert(this.veil);

		this.parent._mousedownListener =  (function(event){
			var data = $A(arguments);
			this.vx = this.getMouseX(data[1],event);
			this.vy = this.getMouseY(data[1],event);
			this.startDrag();
		}).bindAsEventListener(this,this.parent);
		
		this.parent.observe("mousedown",this.parent._mousedownListener);
	},
	destroy : function(){
		this.childs.each(function(child){
			$(child).setStyle({cursor:"default"});
			$(child).stopObserving("click",$(child)._clickListener);
			$(child)._clickListener = null;
		});
		this.parent.stopObserving("mousedown",this.parent._mousedownListener);
		this.parent._mousedownListener = null;
		$(document.body).stopObserving("mouseup",this.mouseUp);
		$(document.body).stopObserving("mousemove",this.mouseMove);
		this.reset();this.veil.remove();
	},
	getSelected : function(){
		var result = this.childs.without(this.veil).findAll(function(div){
			return div.selected;
		});
		return result;
	},
	reset : function(){
		//alert("kkk--" + this.getSelected().length);
		this.getSelected().each((function(value){
			this.cancel(value);
		}).bind(this));
	},
	selectAll : function(){
		this.childs.without(this.veil).each((function(value){
			this.select(value);
		}).bind(this));
	},
	getMouseX :function(element,event){
		return event.pointerX()-$(element).cumulativeOffset()[0];
	},
	getMouseY :function(element,event){
		return event.pointerY()-$(element).cumulativeOffset()[1];
	},
	getRectangle :function(){
		return {x:0,y:0,width:this.parent.offsetWidth,height:this.parent.offsetHeight};
	},
	startDrag : function(){
		$(document.body).observe("mouseup",this.mouseUp);
		$(document.body).observe("mousemove",this.mouseMove);
	},
	stopDrag :function(){
		this.veil.setStyle({left:0+"px",top:0+"px",width:0+"px",height:0+"px"});
		this.veil.hide();
		$(document.body).stopObserving("mouseup",this.mouseUp);
		$(document.body).stopObserving("mousemove",this.mouseMove);
	},
	hitTest : function(ctrlKey){
		var x = this.veil.offsetLeft-this.calculateParentOffset()[0];
		var y = this.veil.offsetTop-this.calculateParentOffset()[1];
		var width = this.veil.offsetWidth;
		var height = this.veil.offsetHeight;
		var divs = this.parent.getElementsByTagName("div");
		$A(divs).without(this.veil).each((function(div){
			var dx = div.offsetLeft;
			var dy = div.offsetTop;
			var dwidth = div.offsetWidth;
			var dheight = div.offsetHeight;
			if((x+width)>=dx && x<=(dx+dwidth) && (y+height)>=dy && y<=(dy+dheight)){
				this.select(div);
			}else{
				if(!ctrlKey)
					this.cancel(div);
			}
		}).bind(this));
	},
	select : function(div){
		$(div).removeClassName("selector_cancel");
		$(div).addClassName("selector_select");
		$(div).selected = true;
	},
	cancel : function(div){
		$(div).removeClassName("selector_select");
		$(div).addClassName("selector_cancel");
		$(div).selected = false;
	},
	calculateParentOffset : function(){
		if(this.veil.offsetParent==this.parent)
			return [0,0];
		else
			return this.parent.positionedOffset();
	},
	drawVeil : function(event){
		this.veil.show();
		var mx = this.getMouseX(this.parent,event);
		var my = this.getMouseY(this.parent,event);
		
		var offsetWidth = mx-this.vx;
		var offsetHeight = my-this.vy;
		var rectangle = this.getRectangle();
		
		if(offsetWidth<0){
			var left = this.vx+offsetWidth;
			var width = Math.abs(offsetWidth);
			
			if(left>rectangle.x){
				this.veil.setStyle({left:(left+this.calculateParentOffset()[0])+"px"});
				this.veil.setStyle({width:width+"px"});
			}else{
				this.veil.setStyle({left:(rectangle.x+this.calculateParentOffset()[0])+"px"});
				this.veil.setStyle({width:left+width+"px"});
			}
		}else{
			var left = this.vx;
			var width = offsetWidth;
			
			if(left>rectangle.x)
				this.veil.setStyle({left:(left+this.calculateParentOffset()[0])+"px"});
			else
				this.veil.setStyle({left:(rectangle.x+this.calculateParentOffset()[0])+"px"});
				
			if(width<rectangle.width-left)
				this.veil.setStyle({width:width+"px"});
			else
				this.veil.setStyle({width:(rectangle.width-left)+"px"});
		}
		
		if(offsetHeight<0){
			var top = this.vy+offsetHeight;
			var height = Math.abs(offsetHeight);
			if(top>rectangle.y){
				this.veil.setStyle({top:(top+this.calculateParentOffset()[1])+"px"});
				this.veil.setStyle({height:height+"px"});
			}else{
				this.veil.setStyle({top:(rectangle.y+this.calculateParentOffset()[1])+"px"});
				this.veil.setStyle({height:top+height+"px"});
			}
		}else{
			var top = this.vy;
			var height = Math.abs(offsetHeight);
			
			if(top>rectangle.y)
				this.veil.setStyle({top:(top+this.calculateParentOffset()[1])+"px"});
			else
				this.veil.setStyle({top:(rectangle.y+this.calculateParentOffset()[1])+"px"});
			
			if(height<rectangle.height-top)
				this.veil.setStyle({height:height+"px"});
			else
				this.veil.setStyle({height:(rectangle.height-top)+"px"});
		}
		
		this.hitTest(event.ctrlKey);
	},
	mouseMove : function(event){
		this.drawVeil(event);
	},
	mouseUp : function(event){
		this.stopDrag();
	}
});

var SingleSelector=Class.create({
	initialize : function(parent, selectedCallBack){
		this.selectedCallBack=selectedCallBack;
		this.selectedItem=null;
		this.oldSelectedItem=null;
		this.parent=document.getElementById(parent);
		if(this.parent==null)return ;
		this.childs = this.parent.getElementsByTagName("div");
		for(var i=0; i<this.childs.length; i++){
			$(this.childs[i]).setStyle({cursor:"pointer"});
			$(this.childs[i]).clickListener= this.selected.bind(this, this.childs[i]);
			$(this.childs[i]).observe("click", $(this.childs[i]).clickListener);
		}
	},
	selected:function(selectedItem){
	
		this.oldSelectedItem=this.selectedItem;
		if(this.oldSelectedItem != null)
			this.oldSelectedItem.className="stuff_item";
		
		for(var i=0; i<this.childs.length; i++){
			if(selectedItem==this.childs[i]){
				selectedItem.className="stuff_item selector_select";	
				this.selectedItem=selectedItem;
				break;
			}
		}
		this.selectedCallBack(selectedItem);
		
	},
	selectOne:function(i){

		if(this.childs.length<=i){
			return;
		}
		this.selected(this.childs[i]);		
	},
	destroy:function(){
		for(var i=0; i<this.childs.length; i++){
			$(this.childs[i]).stopObserving("click", $(this.childs[i]).clickListener);
		}
	}
});
